﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace FlexFlow
{
    /// <summary>
    /// 表示操作执行器，为Manager操作提供链式支持
    /// </summary>
    public class OperateRunner
    {
        /// <summary>
        /// 表示当前操作的操作结果
        /// </summary>
        public OperateResult CurrentResult { get; private set; }

        public OperateRunner()
        {
            this.CurrentResult = OperateResult.SuccessResult();
        }

        /// <summary>
        /// 判断执行下一个操作
        /// </summary>
        /// <param name="expression">
        /// 操作表达式
        /// </param>
        /// <param name="failCode">
        /// 如果操作失败，则返回此代码
        /// </param>
        /// <param name="failMessage">
        /// 如果操作失败，则返回此消息
        /// </param>
        /// <returns>
        /// this
        /// </returns>
        public OperateRunner Next(Expression<Func<OperateRunner, bool>> expression, string failMessage, Nullable<int> failCode)
        {
            if (this.CurrentResult.ResultCode == 200)
            {
                var func = expression.Compile();
                if (func(this))
                {
                    CurrentResult = OperateResult.SuccessResult(true);
                }
                else
                {
                    CurrentResult = new OperateResult()
                    {
                        ResultCode = (int)failCode,
                        Message = failMessage
                    };
                }
            }

            return this;
        }
        /// <summary>
        /// 判断执行下一个操作
        /// </summary>
        /// <param name="func">
        /// 操作函数
        /// </param>
        /// <param name="failCode">
        /// 如果操作失败，则返回此代码
        /// </param>
        /// <param name="failMessage">
        /// 如果操作失败，则返回此消息
        /// </param>
        /// <returns>
        /// this
        /// </returns>
        public OperateRunner Next(Func<bool> func, string failMessage, Nullable<int> failCode)
        {
            if (this.CurrentResult.ResultCode == 200)
            {
                if (!func())
                {
                    CurrentResult = OperateResult.SuccessResult(true);
                }
                else
                {
                    CurrentResult = new OperateResult()
                    {
                        ResultCode = (int)failCode,
                        Message = failMessage
                    };
                }
            }

            return this;
        }
        /// <summary>
        /// 判断执行下一个操作
        /// </summary>
        /// <param name="expression">
        /// 操作表达式
        /// </param>
        /// <param name="failCode">
        /// 如果操作失败，则返回此代码
        /// </param>
        /// <param name="failMessage">
        /// 如果操作失败，则返回此消息
        /// </param>
        /// <returns>
        /// this
        /// </returns>
        public OperateRunner Next(Expression<Func<OperateRunner, OperateResult>> expression, string failMessage, Nullable<int> failCode)
        {
            if (this.CurrentResult.ResultCode == 200)
            {
                var func = expression.Compile();
                OperateResult res = func(this);
                if (res.ResultCode == 200)
                {
                    CurrentResult = res;
                }
                else
                {
                    CurrentResult = new OperateResult()
                    {
                        ResultCode = (int)failCode,
                        Message = failMessage,
                        InnerResult = res
                    };
                }
            }

            return this;
        }

    }
}
